﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.Threading;
using System.Xml.Linq;
using System.IO.MemoryMappedFiles;

namespace LADA
{
    public partial class MainWindow : Form
    {
        //  Panel默认颜色
        private Color PanelNormalColor = Color.FromArgb(120,75,75,75);
        //  Panel鼠标移入颜色
        private Color PanelEnterColor = Color.FromArgb(160,75,75,75);
        //  Button默认颜色
        private Color ButtonNormalColor = Color.FromArgb(80,217,217,217);
        //  Button鼠标移入颜色
        private Color ButtonEnterColor = Color.FromArgb(80,175,175,175);
        //  配置文件路径
        string configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "resource", "config.json");
        // 定义 Conda 环境
        string condaEnvName = "lada";
        //  Python文件路径
        string pythonFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Python", "script.py");
        //  Json对象
        private JObject jsonConfig = new JObject();
        // 操作方案索引
        private int operationIndex = 0;
        // 启用checkBox状态改变事件
        private bool checkBoxEnable = false;
        // 日志级别枚举
        private enum LogLevel { Info, Warning, Error,Custom }
        // python脚本执行线程
        private Thread scriptThread = null;
        // 日志线程
        private Thread logThread = null;
        private Process process = null;

        public MainWindow()
        {
            InitializeComponent();
            panel1.MouseEnter += Panel_MouseEnter;
            panel1.MouseLeave += Panel_MouseLeave;
            checkBox1.MouseEnter += (sender, e) => { panel1.BackColor = PanelEnterColor; };
            checkBox1.MouseLeave += (sender, e) => { panel1.BackColor = PanelNormalColor; };
            panel2.MouseEnter += Panel_MouseEnter;
            panel2.MouseLeave += Panel_MouseLeave;
            checkBox2.MouseEnter += (sender, e) => { panel2.BackColor = PanelEnterColor; };
            checkBox2.MouseLeave += (sender, e) => { panel2.BackColor = PanelNormalColor; };
            panel3.MouseEnter += Panel_MouseEnter;
            panel3.MouseLeave += Panel_MouseLeave;
            checkBox3.MouseEnter += (sender, e) => { panel3.BackColor = PanelEnterColor; };
            checkBox3.MouseLeave += (sender, e) => { panel3.BackColor = PanelNormalColor; };
            panel4.MouseEnter += Panel_MouseEnter;
            panel4.MouseLeave += Panel_MouseLeave;
            checkBox4.MouseEnter += (sender, e) => { panel4.BackColor = PanelEnterColor; };
            checkBox4.MouseLeave += (sender, e) => { panel4.BackColor = PanelNormalColor; };
            panel5.MouseEnter += Panel_MouseEnter;
            panel5.MouseLeave += Panel_MouseLeave;
            checkBox5.MouseEnter += (sender, e) => { panel5.BackColor = PanelEnterColor; };
            checkBox5.MouseLeave += (sender, e) => { panel5.BackColor = PanelNormalColor; };
            panel6.MouseEnter += Panel_MouseEnter;
            panel6.MouseLeave += Panel_MouseLeave;
            checkBox6.MouseEnter += (sender, e) => { panel6.BackColor = PanelEnterColor; };
            checkBox6.MouseLeave += (sender, e) => { panel6.BackColor = PanelNormalColor; };
            panel7.MouseEnter += Panel_MouseEnter;
            panel7.MouseLeave += Panel_MouseLeave;
            checkBox7.MouseEnter += (sender, e) => { panel7.BackColor = PanelEnterColor; };
            checkBox7.MouseLeave += (sender, e) => { panel7.BackColor = PanelNormalColor; };
            panel8.MouseEnter += Panel_MouseEnter;
            panel8.MouseLeave += Panel_MouseLeave;
            checkBox8.MouseEnter += (sender, e) => { panel8.BackColor = PanelEnterColor; };
            checkBox8.MouseLeave += (sender, e) => { panel8.BackColor = PanelNormalColor; };
            allButton.Click += Button_Click;
            allButton.MouseEnter += Button_MouseEnter;
            allButton.MouseLeave += Button_MouseLeave;
            resetButton.Click +=  Button_Click;
            resetButton.MouseEnter += Button_MouseEnter;
            resetButton.MouseLeave += Button_MouseLeave;
            startButton.Click += Button_Click;
            startButton.MouseEnter += Button_MouseEnter;
            startButton.MouseLeave += Button_MouseLeave;
            generalSetButton.Click += Button_Click;
            generalSetButton.MouseEnter += Button_MouseEnter;
            generalSetButton.MouseLeave += Button_MouseLeave;
            advancSetButton.Click += Button_Click;
            advancSetButton.MouseEnter += Button_MouseEnter;
            advancSetButton.MouseLeave += Button_MouseLeave;
            checkBox1.CheckedChanged += CheckBox_CheckedChanged;
            checkBox2.CheckedChanged += CheckBox_CheckedChanged;
            checkBox3.CheckedChanged += CheckBox_CheckedChanged;
            checkBox4.CheckedChanged += CheckBox_CheckedChanged;
            checkBox5.CheckedChanged += CheckBox_CheckedChanged;
            checkBox6.CheckedChanged += CheckBox_CheckedChanged;
            checkBox7.CheckedChanged += CheckBox_CheckedChanged;
            checkBox8.CheckedChanged += CheckBox_CheckedChanged;
            FormClosing += MainWindow_Closing;

            // 日志线程
            logThread = new Thread(LogService);
            logThread.Start();
        }
        /// <summary>
        /// 主窗口加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_Load(object sender, EventArgs e)
        {
            try
            {
                string filePath = "shared_memory.bin";
                int capacity = 1024;
                // 打开或创建共享内存文件
                using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, capacity))
                {
                    using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
                    {
                        // 清空共享内存
                        byte[] zeroBuffer = new byte[capacity];
                        accessor.WriteArray(0, zeroBuffer, 0, capacity);

                        // 准备要写入的数据
                        string response = "C#:alive";
                        byte[] data = Encoding.UTF8.GetBytes(response);

                        // 写入新数据
                        accessor.WriteArray(0, data, 0, data.Length);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发生错误: {ex.Message}");
            }
            try
            {
                if (File.Exists(configFilePath))
                {
                    string jsonContent = File.ReadAllText(configFilePath, System.Text.Encoding.UTF8);
                    jsonConfig = JObject.Parse(jsonContent);
                    // 今日开放关卡
                    DateTime now = DateTime.Now;
                    TimeSpan timeGap = TimeSpan.FromHours(4);
                    DateTime newTime = now - timeGap;
                    int originalDayOfWeek = (int)newTime.DayOfWeek;
                    // 调整为 0 表示周一，1 表示周二，...，6 表示周日
                    int dayOfWeek = (originalDayOfWeek + 6) % 7;
                    string tip = "今日关卡小提示：\n";
                    if (dayOfWeek == 6)
                    {
                        tip = tip + "芯核狩猎：\n今日全部开放！\n深空试炼：\n今日全部开放！\n赶紧刷起来吧！";
                    }
                    else 
                    {
                        tip = tip + "芯核狩猎：\n";
                        JArray items = (JArray)jsonConfig["战斗方案"]["芯核狩猎"]["区域列表"];
                        for (int i = 0; i < items.Count; i++)
                        {
                            string item = items[i].ToString();
                            JArray open_time = (JArray)jsonConfig["战斗方案"]["芯核狩猎"]["区域开放时间"][item];
                            if (open_time.Any(token => (int)token == dayOfWeek))
                            {
                                JArray rewards = (JArray)jsonConfig["战斗方案"]["芯核狩猎"]["区域奖励掉落"][item];
                                string[] list = rewards.Select(token => token.ToString()).ToArray();
                                tip = tip + item + "：" + string.Join("、", list) + "\n";
                            }
                        }
                        tip = tip + "深空试炼：\n";
                        items = (JArray)jsonConfig["战斗方案"]["深空试炼"]["轨道列表"];
                        for (int i = 0; i < items.Count; i++)
                        {
                            string item = items[i].ToString();
                            JArray open_time = (JArray)jsonConfig["战斗方案"]["深空试炼"]["轨道开放时间"][item];
                            if (open_time.Any(token => (int)token == dayOfWeek))
                            {
                                tip = tip + item + "：金币、钻石、极空许愿券\n";
                            }
                        }
                    }
                    tipLabel.Text = tip;
                    // 操作方案绑定到组件
                    JArray operations = (JArray)jsonConfig["操作方案"]["方案列表"];
                    for (int i = 0; i < operations.Count; i++)
                    {
                        if (operations[i]["方案名"].Equals(jsonConfig["操作方案"]["方案启用"]))
                        {
                            operationIndex = i;
                            checkBox1.Checked = (bool)operations[i]["方案操作"][checkBox1.Text];
                            checkBox2.Checked = (bool)operations[i]["方案操作"][checkBox2.Text];
                            checkBox3.Checked = (bool)operations[i]["方案操作"][checkBox3.Text];
                            checkBox4.Checked = (bool)operations[i]["方案操作"][checkBox4.Text];
                            checkBox5.Checked = (bool)operations[i]["方案操作"][checkBox5.Text];
                            checkBox6.Checked = (bool)operations[i]["方案操作"][checkBox6.Text];
                            checkBox7.Checked = (bool)operations[i]["方案操作"][checkBox7.Text];
                            checkBox8.Checked = (bool)operations[i]["方案操作"][checkBox8.Text];
                            checkBoxEnable = true;
                        }
                    }

                }
                else
                {
                    Console.WriteLine("未找到 Config 文件夹下的 config.json 文件。");
                }
            }
            catch (JsonException ex)
            {
                Console.WriteLine($"JSON 解析错误: {ex.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发生未知错误: {ex.Message}");
            }
        }
        /// <summary>
        /// 主窗口关闭事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_Closing(object sender, FormClosingEventArgs e)
        {
            // 询问用户是否真的要关闭
            DialogResult result = MessageBox.Show("你确定要关闭此窗口吗？", "确认关闭", MessageBoxButtons.YesNo);
            if (result == DialogResult.No)
            {
                // 如果用户选择否，则取消关闭操作
                e.Cancel = true;
            }
            else
            {
                // 向共享内存中写入终止程序信号
                using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile("shared_memory.bin", FileMode.OpenOrCreate, null, 1024))
                {
                    using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
                    {
                        string response = "C#:kill";
                        byte[] data = Encoding.UTF8.GetBytes(response);
                        accessor.WriteArray(0, data, 0, data.Length);
                    }
                }
                // 结束 process
                if (process != null && !process.HasExited)
                {
                    try
                    {
                        // 终止 Python 进程
                        process.Kill();
                        process.WaitForExit();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"终止 Python 进程时出错: {ex.Message}");
                    }
                }
                // 停止python脚本线程
                if (scriptThread != null && scriptThread.IsAlive)
                {
                    Console.WriteLine("正在停止线程...");
                    scriptThread.Abort();
                }
            }
        }
        /// <summary>
        /// Panel鼠标移入事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Panel_MouseEnter(object sender, EventArgs e) {
            if (sender is Panel panel)
            {
                panel.BackColor = PanelEnterColor;
            }
        }
        /// <summary>
        /// Panel鼠标移出事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Panel_MouseLeave(object sender, EventArgs e)
        {
            if (sender is Panel panel)
            {
                panel.BackColor = PanelNormalColor;
            }
        }
        /// <summary>
        /// 按钮鼠标移入事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_MouseEnter(object sender, EventArgs e)
        {
            if (sender is Label button)
            {
                button.BackColor = ButtonEnterColor;
            }
        }
        /// <summary>
        /// 按钮鼠标移出事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_MouseLeave(object sender, EventArgs e)
        {
            if (sender is Label button)
            {
                button.BackColor = ButtonNormalColor;
            }
        }
        /// <summary>
        /// 按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, EventArgs e)
        {
            if (sender is Label button)
            {
                if (button.Text == "全选")
                {
                    checkBox1.Checked = true;
                    checkBox2.Checked = true;
                    checkBox3.Checked = true;
                    checkBox4.Checked = true;
                    checkBox5.Checked = true;
                    checkBox6.Checked = true;
                    checkBox7.Checked = true;
                    checkBox8.Checked = true;
                }
                else if (button.Text == "清空")
                {
                    checkBox1.Checked = false;
                    checkBox2.Checked = false;
                    checkBox3.Checked = false;
                    checkBox4.Checked = false;
                    checkBox5.Checked = false;
                    checkBox6.Checked = false;
                    checkBox7.Checked = false;
                    checkBox8.Checked = false;
                }
                else if (button.Text == "Link Start!")
                {
                    SetControlsEnabled(false);
                    button.Text = "STOP";
                    try
                    {
                        string filePath = "shared_memory.bin";
                        int capacity = 1024;
                        // 打开或创建共享内存文件
                        using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, capacity))
                        {
                            using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
                            {
                                // 清空共享内存
                                byte[] zeroBuffer = new byte[capacity];
                                accessor.WriteArray(0, zeroBuffer, 0, capacity);

                                // 准备要写入的数据
                                string response = "C#:alive";
                                byte[] data = Encoding.UTF8.GetBytes(response);

                                // 写入新数据
                                accessor.WriteArray(0, data, 0, data.Length);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"发生错误: {ex.Message}");
                    }
                    //Python脚本线程
                    scriptThread = new Thread(ExecutePythonScript);
                    scriptThread.Start();
                }
                else if (button.Text == "STOP")
                {
                    // 向共享内存中写入终止程序信号
                    using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile("shared_memory.bin", FileMode.OpenOrCreate, null, 1024))
                    {
                        using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
                        {
                            string response = "C#:kill";
                            byte[] data = Encoding.UTF8.GetBytes(response);
                            accessor.WriteArray(0, data, 0, data.Length);
                        }
                    }
                    SetControlsEnabled(true);
                    button.Text = "Link Start!";
                    AppendLog($"[{DateTime.Now:yyy-MM-dd HH:mm:ss}]\nERROR - 中止python脚本执行...", LogLevel.Error);
                    // 结束 process
                    if (process != null && !process.HasExited)
                    {
                        try
                        {
                            // 终止 Python 进程
                            process.Kill();
                            process.WaitForExit();
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"终止 Python 进程时出错: {ex.Message}");
                        }
                    }
                    // 停止python脚本线程
                    if (scriptThread != null && scriptThread.IsAlive)
                    {
                        Console.WriteLine("正在停止线程...");
                        scriptThread.Abort();
                    }
                }
                else if (button.Text == "常规设置")
                {
                    generalSetButton.ForeColor = Color.DodgerBlue;
                    generalSetButton.BorderStyle = BorderStyle.FixedSingle;
                    advancSetButton.ForeColor = Color.White;
                    advancSetButton.BorderStyle = BorderStyle.None;
                    advanceSetPanel.Visible = false;
                }
                else if (button.Text == "高级设置")
                {
                    generalSetButton.ForeColor = Color.White;
                    generalSetButton.BorderStyle = BorderStyle.None;
                    advancSetButton.ForeColor = Color.DodgerBlue;
                    advancSetButton.BorderStyle = BorderStyle.FixedSingle;
                    advanceSetPanel.Visible = true;
                }

            }
        }
        /// <summary>
        /// CheckBox点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if(!checkBoxEnable){ return; }
            if (sender is CheckBox checkBox) 
            {
                string key = "";
                switch (checkBox.Text)
                {
                    case "游戏唤醒":
                        key = "游戏唤醒";
                        break;
                    case "日常交互":
                        key = "日常交互";
                        break;
                    case "每日礼包":
                        key = "每日礼包";
                        break;
                    case "零点追踪":
                        key = "零点追踪";
                        break;
                    case "芯核狩猎":
                        key = "芯核狩猎";
                        break;
                    case "深空试炼":
                        key = "深空试炼";
                        break;
                    case "体力赠送":
                        key = "体力赠送";
                        break;
                    case "一键领取":
                        key = "一键领取";
                        break;
                }
                if (!key.Equals("")) {
                    bool flag = (bool)jsonConfig["操作方案"]["方案列表"][operationIndex]["方案操作"][key];
                    jsonConfig["操作方案"]["方案列表"][operationIndex]["方案操作"][key] = !flag;
                }
                Encoding utf8WithoutBom = new UTF8Encoding(false);
                string updatedJson = jsonConfig.ToString(Formatting.Indented);
                using (StreamWriter writer = new StreamWriter(configFilePath, false, utf8WithoutBom))
                {
                    writer.Write(updatedJson);
                }
            }
        }
        /// <summary>
        /// 设置控件是否启用
        /// </summary>
        /// <param name="enabled"></param>
        private void SetControlsEnabled(bool enabled)
        {
            allButton.Enabled = enabled;
            resetButton.Enabled = enabled;
            checkBox1.Enabled = enabled;
            checkBox2.Enabled = enabled;
            checkBox3.Enabled = enabled;
            checkBox4.Enabled = enabled;
            checkBox5.Enabled = enabled;
            checkBox6.Enabled = enabled;
            checkBox7.Enabled = enabled;
            checkBox8.Enabled = enabled;
        }
        /// <summary>
        /// 日志输出
        /// </summary>
        private void LogService()
        {
            var logServer = new UdpLogServer(5145);
            logServer.LogReceived += entry =>
            {
                LogLevel level = LogLevel.Info;
                switch (entry.Level.ToUpper())
                {
                    case "ERROR": level = LogLevel.Error; break;
                    case "WARNING": level = LogLevel.Custom; break;
                    case "INFO": level = LogLevel.Info; break;
                }
                string log = entry.ToString();
                Console.WriteLine(log);
                // 移除 T 和毫秒部分
                string removedTAndMilliseconds = log.Replace("T", " ").Substring(0, 20);
                // 提取日志级别（如 INFO）
                
                int leftDashIndex = log.IndexOf("] ",  StringComparison.Ordinal);
                int rightDashIndex = log.IndexOf(" - ", StringComparison.Ordinal);
                int secondDashIndex = log.IndexOf(" - ", rightDashIndex + 3, StringComparison.Ordinal);
                string logLevel = log.Substring(leftDashIndex + 2, rightDashIndex - leftDashIndex - 2);
                // 提取日志消息部分
                string logMessage = log.Substring(secondDashIndex + 3);
                AppendLog($"{removedTAndMilliseconds}]\n{logLevel} - {logMessage}", level);

            };
            logServer.Start();
        }
        /// <summary>
        /// 执行python脚本
        /// </summary>
        private void ExecutePythonScript()
        {
            try
            {
                process = new Process();
                // 创建一个新的 ProcessStartInfo 对象
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = "cmd.exe";

                // 构建要执行的命令，激活 Conda 环境并执行 Python 文件
                startInfo.Arguments = $"/C conda activate {condaEnvName} && python {pythonFilePath}";
                startInfo.UseShellExecute = false;
                startInfo.RedirectStandardInput = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                startInfo.CreateNoWindow = true;

                process.StartInfo = startInfo;

                //进程开始执行
                process.Start();

                process.WaitForExit();
                AppendLog($"[{DateTime.Now:yyy-MM-dd HH:mm:ss}]\nCUSTOM - 脚本执行完毕，祝您每天开心~", LogLevel.Custom);
            }
            catch (Exception ex)
            {
                AppendLog($"[{DateTime.Now:yyy-MM-dd HH:mm:ss}]\nERROR - 执行Python文件时发生错误: {ex.Message}", LogLevel.Error);
            }
        }
        /// <summary>
        /// 添加日志到输出框
        /// </summary>
        /// <param name="message"></param>
        /// <param name="level"></param>
        private void AppendLog(string message, LogLevel level = LogLevel.Info)
        {
            Color color = Color.Gray;
            switch (level)
            {
                case LogLevel.Warning:
                    color = Color.Orange;
                    break;
                case LogLevel.Error:
                    color = Color.Red;
                    break;
                case LogLevel.Custom:
                    color = Color.Black;
                    break;
            }
            if (logTextBox.InvokeRequired)
            {
                logTextBox.Invoke(new Action<string, LogLevel>(AppendLog), message, level);
            }
            else
            {
                if (message.Contains("脚本执行完毕，祝您每天开心") || message.Contains("自动代理结束")) {
                    SetControlsEnabled(true);
                    startButton.Text = "Link Start!";
                }
                
                logTextBox.AppendText($"{message}{Environment.NewLine}", color);
                logTextBox.ScrollToBottom();
            }
        }
    }  
}
